package com.neusoft.databus.agent.controller;

import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.neusoft.bizcore.web.dto.result.ResultDTO;
import com.neusoft.databus.agent.interactive.service.CollectorService;
import com.neusoft.databus.common.bean.CommandBean;

import lombok.extern.slf4j.Slf4j;

/**
 * the controller for resource metric collection<br>
 *
 * @author sunchf
 * @date 2018年12月28日 上午10:13:58
 */

@Slf4j
@RestController
@RequestMapping(value = "/api/w/commands")
public class CommandController {

    @Autowired
    private CollectorService collectorService;
    @Resource(name = "asyncCollectionExecutorService")
    private ExecutorService asyncCollectionExecutorService;

    /**
     * handle resource metric collection task
     *
     * @param command the request information for task
     * @return command the request and response information for task
     * @throws Exception
     */
    @PostMapping("/collect")
    public ResultDTO<?> collect(@RequestBody CommandBean command,
            @RequestHeader(name = "stateIdentifier", required = false) String stateIdentifier) throws Exception {

        if (CommandController.log.isDebugEnabled()) {
            CommandController.log.debug("agent receive a collection request, contained resources {}.",
                    command.getResourceBean().stream().map(it -> it.getCode()).collect(Collectors.joining(",")));
        }
        if (command.isAsync()) {
            this.asyncCollectionExecutorService.execute(() -> {
                try {
                    CommandController.this.collectorService.collect(command);
                } catch (final Exception e) {
                    CommandController.log.error("", e);
                }
            });
            return ResultDTO.success();
        } else {
            final CommandBean result = this.collectorService.collect(command);
            return ResultDTO.success(result);
        }
    }

    @PostMapping("/control")
    public ResultDTO<CommandBean> control(@RequestBody CommandBean command,
            @RequestHeader(name = "stateIdentifier", required = false) String stateIdentifier) throws Exception {

        if (CommandController.log.isInfoEnabled()) {
            CommandController.log.info("agent receive a control request: {}:{},{},{} metrics",
                    command.getResourceBean().get(0).getName(),
                    command.getResourceBean().get(0).getCode(),
                    command.getConnectionStr(), command.getResourceBean().get(0).getMetrics().size());
        }
        final CommandBean result = this.collectorService.control(command);
        return ResultDTO.success(result);
    }
}
